<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Expenditure Salary Beta</title>
<style type="text/css">
        body {
            text-align: center;
            font: 15px sans-serif;
        }
        svg {
            font: 12px sans-serif;
        }
        .header {
            font: 15px sans-serif;
        }
        div.tooltip {
            position: absolute;
            text-align: left;
            padding: 8px;
            font: 10px sans-serif;
            background: #ddd;
            border: solid 1px #aaa;
            border-radius: 8px;
            /*pointer-events: none;*/
        }
        .sunburst {
        	margin: 20px;
        	padding: 10px;
        	border: solid 1px #aaa;
        }
        
        path {
  			cursor: pointer;
  			stroke: #fff;
  			fill-rule: evenodd;
		}
       
    </style>
    <script type="text/javascript" src="../js/d3.js"></script>
    <script type='text/javascript'>
    	 
    </script>
</head>
<body>
	<script type='text/javascript'>
	// Map object for caching data
	var d_cache;
	
	var header = d3.select("body").append("div").attr("id", "sunburstDiv");
	header.html("<a href='../index.html'><img src='../images/home_icon.png'></a> งบประมาณรายจ่ายประเภทเงินเดือนของบุคลากร มหาวิทยาลัยราชภัฏรำไพพรรณี <br/>" +
				"<p id='error_msg'></p>");

	// Prepare radio box input element
	d3.json("../XPD005Controller?parameter=radioBox", function (error, data) {
    	var radio = "ปีงบประมาณ";
    	var check = true;
    	
    	data.forEach(function (d) {
        	if (check) {
            	radio += " <input type='radio' name='year' value=" + d.period + " id='radioSun' checked='checked' >" + d.period;
            	check = false;
        	} else {
            	radio += " <input type='radio' name='year' value=" + d.period + " id='radioSun' >" + d.period;
        	}
        	
    	});
    	
    	header.append("div").attr("id", "radioBox").html(radio);
    	firstDrawSunburst(document.getElementById('radioSun').value);
	}); // End of radio box creator
	
	
	
	
	
		function firstDrawSunburst(periodYear){
			
			// ===== Draw Sunburst code start from this line =====
			var width = 1024,
		     height = 690,
		     radius = (Math.min(width, height) / 2) - 10;
		
			var x = d3.scale.linear()
			     .range([0, 2 * Math.PI]);
		
			var y = d3.scale.linear()
			     .range([0, radius]);
		
		 	// var color = d3.scale.category10();
		 	
		 	// set color scale range with empty domain (color mapping range index with dynamically added domain)
		 	//var color = d3.scale.ordinal().range(['#03fdf2','#5077da','#85e02c']);
		 	var color = d3.scale.ordinal().range(['#f9d5d8','#00ec03','#00db01','#bdfebc','#f3be4b','#f8ce78','#feda54']);
			
		 	var svg = d3.select("body").append("svg")
		    .attr("width", width)
		    .attr("height", height)
		    .append("g")
		    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
		 	
		 	var partition = d3.layout.partition()
		    .value(function (d) {
		        return d.amount;
		    });

			var arc = d3.svg.arc()
		    .startAngle(function (d) {
		        return Math.max(0, Math.min(2 * Math.PI, x(d.x)));
		    })
		    .endAngle(function (d) {
		        return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));
		    })
		    .innerRadius(function (d) {
		        return Math.max(0, y(d.y));
		    })
		    .outerRadius(function (d) {
		        return Math.max(0, y(d.y + d.dy));
		    });
			
		 	var oldData;
		 	var oldNodes;
		 	var currentDepth = 0;
			// Get JSON data from controller
			d3.json("../XPD005Controller?parameter=getExpenditureSalary&periodYear="+periodYear,function(error,data){
				oldData = data;
				// First time to get new data, keep it in cache storage
				d_cache = d3.map([{year: periodYear, data: null}],function(e){ return e.year;});
				d_cache.set(periodYear,{year: periodYear, data: data});
				console.log("map: %O",d_cache);
				
				var g = svg.selectAll("g")
		           .data(partition.nodes(data))
		           .enter().append("g");
				
				var path = g.append("path")
		      		.attr("d", arc)
		      		//.style("fill", function(d) { return color((d.children ? d : d.parent).name); })
		      		.style("fill", function(d) { return color(d.children ? d.name : d.parent.name+"."+d.name); })
		      		.on("click", click)
		      		.each(function(d) {
		                this.x0 = d.x;
		                this.dx0 = d.dx;
		            });
				//console.log("paths: %O\ncolor.domain(): %O",d3.selectAll('path'),color.domain());
				
				// insert onchange handler function (change()) on radio box DOM
		  		d3.selectAll("#radioSun").on("change", function change() {
		  			// search existing data from cache storage may live here
		  			var selected_year = this.value;
		  			if(d_cache.has(selected_year)){
		  				console.log("cache hit: %O",d_cache);
		  				changeHandler(d_cache.get(selected_year).data);
		  			}else{
		  				d3.json("../XPD005Controller?parameter=getExpenditureSalary&periodYear="+selected_year, function (error,newdata){
		  					d_cache.set(selected_year,{year: selected_year, data: newdata});
		  					console.log("cache miss: %O",d_cache);
		  					changeHandler(newdata);
		  				});
		  			}
		  			
		  			function changeHandler(newdata) {
		  				oldNodes = partition(oldData);
		  				oldData = newdata;
		  				console.log("old nodes: %O", oldNodes);
		  				
		  				var nodes = partition.nodes(newdata);
		  				// Keep previous position before update datum in each nodes
		   				path.each(function(d) {
	                			this.x0 = d.x;
	                			this.dx0 = d.dx;
	            			});
		  				
		  				g.data(nodes);
		      			path.data(nodes)
		      				.transition()
		        			.duration(1400)
		       				.attrTween("d", arcTweenUpdate);
		      			
		      			
		      			var texts = d3.selectAll('text');
		       			texts.each(function(d) {
		       				this.oldAmount = d.amount;
                			this.x0 = d.x;
                			this.dx0 = d.dx;
                			//console.log("text(d): %O",this);
            			});
		       			
		       			texts.data(nodes);
		       			//console.log("texts: %O",texts);
		       			
		       			texts
		       			//.style("fill-opacity", 0.4)
				      	.transition()
				        .duration(1000)
				        .attr('text-anchor','middle')
				        .attr("transform", function(d) {
				            return "translate(" + arc.centroid(d) + ")";
				        })
				        .style('fill-opacity',1);
				        /* .each("end", function(d) {
				          d3.select(this).style("fill-opacity", "1");
				        }); */
		       			
		       			// Update associated text elements
		       			var tspan_name = g.select("#tspan_name");
				        tspan_name.data(nodes);
		       			tspan_name.text(function (d){
		       				return d.name;
		       			});
		   				var tspan_amount = g.select("#tspan_amount");
		   				/*tspan_amount.each(function(d){
		   					this.oldAmount = d.amount;
		   				});*/
		   				tspan_amount.data(nodes);
		   				tspan_amount.transition().duration(1000).tween('text',function(d){
		   					//console.log("tspan_amount.transition().tween(d): %O",this);
		   					//var i = d3.interpolate(this.oldAmount,d.amount);
		   					var i = d3.interpolate(0.01,d.amount);
		   					return function (t) {
		   						this.textContent = i(t);
		   					};
		   				}).each("end",function (d){
		   					this.textContent =  d.amount.toLocaleString("th-TH")+" THB";
		   				});
		       			
		       			
		       			
				        
		       			
		  			} // End of change handler in change event anonymous function
		  		}); // End of on change method of RadioBox

		  		// Append svg:text 
				var text = g.append("text")
				.style("fill-opacity", 1)
	       		//.attr("x", function(d) { return y(d.y); })
	       		.attr('text-anchor', 'middle')
	       		.attr("dx", "0") // margin
	       		.attr("dy", ".35em") // vertical-align
	       		.attr("transform", function(d) {
			    	return "translate(" + arc.centroid(d) + ")";
			    })
			    .on("click",click);
	       		
				text.append("tspan").attr("id","tspan_name").attr("x",0).attr("dy","1.2em").text(function (d){
	       			return d.name;
	       		});
	       		text.append("tspan").attr("id","tspan_amount").attr("x",0).attr("dy","1.0em").text(function (d){
					return d.amount.toLocaleString("th-TH")+" THB";
				});
	       		

		  		function click(d) {
		  			currentDepth = d.depth;
		    		console.log('click()-> d: %O\ncurrentDepth: %O',d,currentDepth);
		    		
		    		path.transition()
		      			.duration(1000)
		      			.attrTween("d", arcTween(d));
		      			
				  	text.style("visibility", function(e) {
				          return isParentOf(d, e) ? null : d3.select(this).style("visibility");
			        })
			      	.transition()
			        .duration(1000)
			        .attr("text-anchor", 'middle')
			        .attrTween("transform", function(d) {
			          return function() {
			          	return "translate(" + arc.centroid(d) + ")";
			          };
			        })
			        .style("fill-opacity", function(e) { return isParentOf(d, e) ? 1 : 1e-6; })
			        .each("end", function(e) {
			          d3.select(this).style("visibility", isParentOf(d, e) ? null : "hidden");
			        });
		    		
		    		
		  		} // End of click function
		  		
		  		
		  		function isParentOf(p, c) {
		  		  if (p === c) return true;
		  		  if (p.children) {
		  		    return p.children.some(function(d) {
		  		      return isParentOf(d, c);
		  		    });
		  		  }
		  		  return false;
		  		}
		  		
		  		
		  		// When zooming: interpolate the scales.
				function arcTween(d) {
				  var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
				      yd = d3.interpolate(y.domain(), [d.y, 1]),
				      yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
				  return function(d, i) {
				    return i
				        ? function(t) { return arc(d); }
				        : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
				  };
				}
				
				function arcTweenUpdate(a) {
					  var i = d3.interpolate({x: this.x0, dx: this.dx0}, a);
					  return function(t) {
					    var b = i(t);
					    this.x0 = b.x;
					    this.dx0 = b.dx;
					    return arc(b);
					  };
				}
				
				
			}); // End of d3.json()
			
		} // Enf of firstDrawSunburst()
		
		
		// ===== End of draw Sunburst code =====
	
        
	</script>
</body>
</html>